#!/bin/bash

# Скрипт для автоматического расчета следующей версии на основе conventional commits
# Анализирует коммиты с последнего тега и определяет тип изменения

set -e

# Функция для получения последнего тега
get_last_tag() {
    if git describe --tags --abbrev=0 >/dev/null 2>&1; then
        git describe --tags --abbrev=0
    else
        echo "v0.0.0"
    fi
}

# Функция для парсинга версии
parse_version() {
    local tag="$1"
    # Убираем префикс 'v' если есть
    if [[ $tag == v* ]]; then
        tag="${tag#v}"
    fi
    
    # Разбиваем на части
    IFS='.' read -r major minor patch <<< "$tag"
    echo "$major $minor $patch"
}

# Функция для анализа коммитов
analyze_commits() {
    local last_tag="$1"
    local commit_type="patch"  # По умолчанию patch
    
    # Получаем коммиты с последнего тега
    if [[ "$last_tag" == "v0.0.0" ]]; then
        # Если тегов нет, анализируем все коммиты
        commits=$(git log --oneline --format="%s")
    else
        # Анализируем коммиты с последнего тега
        commits=$(git log --oneline --format="%s" "${last_tag}..HEAD")
    fi
    
    # Анализируем каждый коммит
    while IFS= read -r commit; do
        if [[ -n "$commit" ]]; then
            # Проверяем на breaking changes
            if [[ "$commit" == *"BREAKING CHANGE:"* ]] || [[ "$commit" == *"feat!:"* ]] || [[ "$commit" == *"refactor!:"* ]]; then
                commit_type="major"
                break
            fi
            
            # Проверяем на новую функциональность
            if [[ "$commit" == feat:* ]] || [[ "$commit" == perf:* ]] || [[ "$commit" == style:* ]]; then
                if [[ "$commit_type" != "major" ]]; then
                    commit_type="minor"
                fi
            fi
        fi
    done <<< "$commits"
    
    echo "$commit_type"
}

# Функция для расчета следующей версии
calculate_next_version() {
    local major="$1"
    local minor="$2"
    local patch="$3"
    local commit_type="$4"
    
    case "$commit_type" in
        "major")
            echo "$((major + 1)).0.0"
            ;;
        "minor")
            echo "$major.$((minor + 1)).0"
            ;;
        "patch")
            echo "$major.$minor.$((patch + 1))"
            ;;
        *)
            echo "$major.$minor.$((patch + 1))"
            ;;
    esac
}

# Основная логика
main() {
    local last_tag=$(get_last_tag)
    local version_parts=($(parse_version "$last_tag"))
    local major="${version_parts[0]}"
    local minor="${version_parts[1]}"
    local patch="${version_parts[2]}"
    
    local commit_type=$(analyze_commits "$last_tag")
    local next_version=$(calculate_next_version "$major" "$minor" "$patch" "$commit_type")
    
    echo "v$next_version"
}

# Запуск
main "$@"
